﻿using System;
using System.Collections.Generic;
using System.Linq;
using cludg.Repository.NHibernate.Sessions;
using NHibernate;
using NHibernate.Linq;
using cludg.Domain.Users;

namespace cludg.Repository.Security.NHibernate
{
	public class SecurityRepository : ISecurityRepository
	{
		protected readonly INHibernateSessionController SessionController;

		public SecurityRepository(INHibernateSessionController sessionController)
		{
			SessionController = sessionController;
		}

		public IEnumerable<User> AllUsers
		{
			get 
			{
				return SessionController.Current.Linq<User>(
					SessionController.Current.CreateCriteria<User>().SetCacheable(true));
			}
		}

		protected IQueryable<UserSecurityInfo> AllInfo
		{
			get
			{
				return SessionController.Current.Linq<UserSecurityInfo>(
					SessionController.Current.CreateCriteria<UserSecurityInfo>().SetCacheable(true));
			}
		}

		public User GetUserById(string userId)
		{
			return SessionController.Current.Get<User>(userId);
		}

		public UserSecurityInfo GetUserSecurityInfo(string id)
		{
			return SessionController.Current.Get<UserSecurityInfo>(id);
		}

		public UserSecurityInfo GetUserSecurityInfoByName(string userName)
		{
			return AllInfo.FirstOrDefault(i => i.Name == userName);
		}

		public UserSecurityInfo GetUserSecurityInfoByEmail(string email)
		{
			return AllInfo.FirstOrDefault(i => i.Email == email);
		}

		public UserSecurityInfo GetUserSecurityInfoByThirPartyIdent(string ident)
		{
			return AllInfo.FirstOrDefault(i => i.ThirdPartyIdent == ident);
		}

		public string AddUser(User user)
		{
			try
			{
				SessionController.Current.SaveOrUpdate(user);
				return user.Id;
			}
			catch (Exception)
			{
				SessionController.Reset();
				throw;
			}
		}

		public void ChangeUserSecurityInfo(string userId, UserSecurityInfo info)
		{
			try
			{
				info.Id = userId;
				SessionController.Current.SaveOrUpdate(info);
			}
			catch (Exception)
			{
				SessionController.Reset();
				throw;
			}
		}

		public void SaveUser(string userId, User user)
		{
			try
			{
				user.Id = userId;
				SessionController.Current.Update(user);
			}
			catch (Exception)
			{
				SessionController.Reset();
				throw;
			}
		}
	}
}
